package com.atguigu.tingshu.user.service.impl;


import cn.binarywang.wx.miniapp.api.WxMaService;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.user.config.WxLoginConfig;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.user.mapper.UserInfoMapper;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.auth0.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.jwt.crypto.sign.RsaSigner;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.security.interfaces.RSAPrivateKey;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Resource
    WxLoginConfig wxLoginConfig;
    @Resource
    RestTemplate restTemplate;
    @Resource
    RedisTemplate redisTemplate;
    //    @Resource
//    WxMaService wxMaService;
    @Resource
    RSAPrivateKey guiguPrivateKey;
    @Resource
    RabbitTemplate rabbitTemplate;

    @Override
    public Object wxLoginGuigu(String code) {
        return wxLogin(code, "1");
    }

    /**
     * sdk登录
     *
     * @param code
     * @return
     */
    @Override
    @SneakyThrows
    public Object wxLoginSdk(String code) {

        return wxLogin(code, "2");
    }

    /**
     * 获取用户信息
     * @return
     */
    @Override
    public Object getUserInfo() {
        //获取用户id
        Long userId = AuthContextHolder.getUserId();
        //查询用户信息
        UserInfo userInfo = getById(userId);
        //转Vo
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(userInfo, userInfoVo);
        //放回
        return userInfoVo;
    }

    @SneakyThrows
    private JSONObject wxLogin(String code, String status) {
        //参数校验
        if (StringUtils.isEmpty(code)) {
            throw new GuiguException(201, "参数错误");
        }
        String openid = null;
        if (status.equals("1")) {
            //手写
            //包装请求url
            String url = wxLoginConfig.getUrl();
            //包装请求参数appid+secret+js_code+grant_type
            url += "&appid=" + wxLoginConfig.getAppId()
                    + "&secret=" + wxLoginConfig.getAppSecret()
                    + "&js_code=" + code;
            //发送get请求
            String s = restTemplate.getForObject(url, String.class);
            JSONObject result = JSONObject.parseObject(s);
            //解析请求结果为json数据
            openid = result.get("openid").toString();
        }
//        else {
//            //sdk
//            //发起登录请求
//             openid = wxMaService.jsCode2SessionInfo(code).getOpenid();
//        }

        //获取openId
        UserInfo userInfo = getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId, openid).last("limit 1"));
        if (userInfo == null) {
            userInfo = new UserInfo();
            userInfo.setWxOpenId(openid);
            userInfo.setNickname("初始用户" + System.currentTimeMillis());
            userInfo.setAvatarUrl("http://192.168.200.130:9000/atguiguts/756dde165db84970b3b74692cc8042f0");
            save(userInfo);
            //初始化用户账户
            rabbitTemplate.convertAndSend("user_and_account_exchange",
                    "user.account", userInfo.getId().toString());

        }
        //TODO 数据预热 MQ广播
        //自定义载荷
        JSONObject paylod = new JSONObject();
        paylod.put("userId", userInfo.getId());
        //每个jwt唯一表示
        String jti = IdWorker.get32UUID();
        paylod.put("jti", jti);
        //生成私钥
        Jwt encode = JwtHelper.encode(paylod.toString(),new RsaSigner(guiguPrivateKey));
        //生成jwt类型token
        String token = encode.getEncoded();
        //只记录用户最后一次登录状态
        redisTemplate.opsForValue().set("User_Login_Id_"+userInfo.getId(), token,1, TimeUnit.DAYS);
        //返回结果初始化
        JSONObject result = new JSONObject();
        result.put("token",token);
        //返回
        return result;
    }

}

